package com.ansion.basedb.storage;

import androidx.annotation.NonNull;

import com.ansion.basedb.storage.api.BaseKeyValueStorage;
import com.ansion.basedb.storage.api.StorageMode;
import com.ansion.basedb.storage.secure.SpStorageImpl;
import com.ansion.basetool.preconditions.Preconditions;
import com.ansion.log.VLog;
import com.ansion.preference.TurboBasePreference;

import java.util.concurrent.ConcurrentHashMap;

class StorageManager {
    /**
     * 使用ConcurrentHashMap解决多线程访问数据不一致的问题
     */
    private static final ConcurrentHashMap<String, BaseKeyValueStorage> storageMap = new ConcurrentHashMap<>();

    public static BaseKeyValueStorage getStorage(@NonNull String tableName) {
        BaseKeyValueStorage storage = storageMap.get(tableName);
        if (storage == null) {//默认取MMKV实现，如果不支持则使用sql kvs
            storage = createStorage(tableName, StorageMode.MODE_SP, StorageMode.MODE_SP);
            storageMap.put(tableName, storage);
        }
        return storage;
    }

    public static BaseKeyValueStorage getStorage(@NonNull String tableName, @StorageMode int mode) {
        return getStorage(tableName, mode, StorageMode.MODE_SP);
    }

    public static BaseKeyValueStorage getStorage(@NonNull String tableName, @StorageMode int mode, int mmkvFallBackMode) {
        int finalMode = getFinalMode(mode, mmkvFallBackMode);
        String key = tableName + finalMode;
        BaseKeyValueStorage storage = storageMap.get(key);
        if (storage == null) {
            storage = createStorage(tableName, mode, StorageMode.MODE_SP);
            if (storage != null)
                storageMap.put(key, storage);
            else
                VLog.e("TAG_STORAGE", "get null storage[%s,%d]", tableName, mode);
        }
        return storage;
    }

    private static BaseKeyValueStorage createStorage(@NonNull String name, @StorageMode int mode, @StorageMode int mmkvFallBackMode) {
        BaseKeyValueStorage kvs = null;
        Preconditions.checkNotEmpty(name);
        int finalMode = getFinalMode(mode, mmkvFallBackMode);
//        if (finalMode == StorageMode.MODE_MMKV) {
//            kvs = LiteStorageManager.getInstance().getStorage(name, true);
//        } else
        if (finalMode == StorageMode.MODE_SP) {
            kvs = new SpStorageImpl(name);
        } else if (finalMode == StorageMode.MODE_ESP) {
            try {
//                throw new RuntimeException("for test");
                kvs = new SecureStorePreference(name);
            } catch (Throwable e) {//android keystore出现异常，不可用
            }

        } else {//走不到这里
            throw new IllegalArgumentException("not support mode:" + finalMode);
        }
        return kvs;
    }

    public static @StorageMode
    int getFinalMode(@StorageMode int mode, int mmkvFallBackMode) {
        if (!TurboBasePreference.mmkvInited) {
            throw new IllegalStateException("you must initMMKV first");
        }
        @StorageMode int finalMode = mode;
        if (mode == StorageMode.MODE_MMKV) {
            if (!TurboBasePreference.MMKVEnable) {
                if (mmkvFallBackMode > 0) {
                    finalMode = mmkvFallBackMode;
                }
            }
        }
        return finalMode;
    }

    public static void clear() {
        storageMap.clear();
    }

}
